package com.jdaoyun.execute;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jdaoyun.a_empcsApi.entity.*;
import com.jdaoyun.a_empcsApi.service.*;
import com.jdaoyun.constant.Type;
import com.jdaoyun.result.R;
import com.jdaoyun.util.DataSender;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 推送数据
 */
@Component
@Slf4j
public class PushCode {

    @Autowired
    private DataSender DataSender;

    @Autowired
    private TEmergencyDiagnosisService emergencyDiagnosisService;

    @Autowired
    private TEmergencyTimeNodeService emergencyTimeNodeService;

    @Autowired
    private TEmergencyTaskTimeService emergencyTaskTimeService;

    @Autowired
    private TEmergencyCallService emergencyCallService;

    @Autowired
    private TMedicalStaffService medicalStaffService;

    @Autowired
    private TCarInfoService carInfoService;

    @Autowired
    private TDriverInfoService driverInfoService;

    @Autowired
    private TOrgInfoService orgInfoService;

    @Autowired
    private TCarRealTimeLocationService carRealTimeLocationService;

    /**
     * 机构数据
     */
    public void orgInfo() {

        log.info("开始推送机构数据");

        List<TOrgInfo> tOrgInfos = orgInfoService.list(null);
        Map<Long, List<TOrgInfo>> groupedByTenantId = tOrgInfos.stream().collect(Collectors.groupingBy(TOrgInfo -> TOrgInfo.getTenantId() != null ? TOrgInfo.getTenantId() : 0L));
        //循环推送
        groupedByTenantId.forEach((tenantId, tOrgInfo) -> {
            tOrgInfo.forEach(orgInfo -> orgInfo.setPushStatus(1));
            orgInfoService.updateBatchById(tOrgInfo);

            int size = tOrgInfo.size(); // 数据量
            log.info("入参：{}", JSONUtil.toJsonStr(tOrgInfo));
            try {
                R<JSONObject> jsonObjectR = DataSender.sendData(Type.AGENCY_INFO, size, JSONUtil.toJsonStr(tOrgInfo), tenantId.intValue());
                log.info("推送机构数据返回结果：{}", jsonObjectR);
            } catch (Exception e) {
                log.error("异常：{}", e);
            }
        });
        log.info("结束推送机构数据");
    }

    /**
     * 车辆数据
     */
    public void carInfo() {
        log.info("开始执行车辆数据推送...");

        //1.查TCarInfo，未推送的
        List<TCarInfo> carInfoList = carInfoService.list(new LambdaQueryWrapper<TCarInfo>().eq(TCarInfo::getPushStatus, 0));
        if (ObjectUtil.isEmpty(carInfoList)) {
            log.error("没有需要推送的车辆数据...");
        }
        // 2. 将 tenantId 一样的过滤成单独的集合
        Map<Long, List<TCarInfo>> groupedByTenantId = carInfoList.stream().collect(Collectors.groupingBy(carInfo -> carInfo.getTenantId() != null ? carInfo.getTenantId() : 0L));
        //3.循环推送
        groupedByTenantId.forEach((tenantId, carInfo) -> {
            carInfo.forEach(
                    car -> {
                        car.setUpdateTime(null);
                        car.setCreateTime(null);
                        car.setPushStatus(null);
                        car.setTenantId(null);
                        //car对象变json字符串
                        String json = "[" + JSONUtil.toJsonStr(car) + "]";
                        log.info("入参：{}", json);
                        try {
                            R<JSONObject> jsonObjectR = DataSender.sendData(Type.VEHICLE_INFO, 1, json, tenantId.intValue());
                            log.info("推送车辆数据返回结果：{}", jsonObjectR);
                            if (jsonObjectR.getCode() == 0 || car.getRetryConunt() >= 5) {
                                car.setPushStatus(1);
                                carInfoService.updateById(car);
                            } else {//就重试5次
                                car.setRetryConunt(car.getRetryConunt() + 1);
                                carInfoService.updateById(car);
                            }
                        } catch (Exception e) {
                            log.error("异常：{}", e);
                        }
                    }
            );
        });
        log.info("结束执行车辆数据推送...");
    }


    /**
     * 司机数据
     */
    public void driverInfo() {
        log.info("开始执行司机数据推送...");

        //1.查TCarInfo，未推送的
        List<TDriverInfo> driverList = driverInfoService.list(new LambdaQueryWrapper<TDriverInfo>().eq(TDriverInfo::getPushStatus, 0));
        if (ObjectUtil.isEmpty(driverList)) {
            log.error("没有需要推送的司机数据...");
        }
        Map<Long, List<TDriverInfo>> groupedByTenantId = driverList.stream().collect(Collectors.groupingBy(TDriverInfo -> TDriverInfo.getTenantId() != null ? TDriverInfo.getTenantId() : 0L));
        //2.循环推送
        groupedByTenantId.forEach((tenantId, driverInfoList) -> {
            driverInfoList.forEach(driverInfo -> {
                driverInfo.setUpdateTime(null);
                driverInfo.setCreateTime(null);
                driverInfo.setPushStatus(null);
                driverInfo.setTenantId(null);

                String json = "[" + JSONUtil.toJsonStr(driverInfo) + "]";
                log.info("入参：{}", json);
                try {
                    R<JSONObject> jsonObjectR = DataSender.sendData(Type.DRIVER_INFO, 1, json, tenantId.intValue());
                    log.info("推送司机数据返回结果：{}", jsonObjectR);
                    if (jsonObjectR.getCode() == 0 || driverInfo.getRetryConunt() >= 5) {
                        driverInfo.setPushStatus(1);
                        driverInfoService.updateById(driverInfo);
                    } else {//就重试5次
                        driverInfo.setRetryConunt(driverInfo.getRetryConunt() + 1);
                        driverInfoService.updateById(driverInfo);
                    }
                } catch (Exception e) {
                    log.error("异常：{}", e);
                }
            });
        });
        log.info("结束执行司机数据推送...");
    }


    /**
     * 医护人员信息
     */
    public void doctorInfo() {
        log.info("开始执行医护人员数据推送...");
        //1.查TMedicalStaff，未推送的
        List<TMedicalStaff> medicalStaffList = medicalStaffService.list(new LambdaQueryWrapper<TMedicalStaff>().eq(TMedicalStaff::getPushStatus, 0));
        if (ObjectUtil.isEmpty(medicalStaffList)) {
            log.error("没有需要推送的医护人员数据...");
        }

        Map<Long, List<TMedicalStaff>> groupedByTenantId = medicalStaffList.stream().collect(Collectors.groupingBy(TMedicalStaff -> TMedicalStaff.getTenantId() != null ? TMedicalStaff.getTenantId() : 0L));
        //2.循环推送
        groupedByTenantId.forEach((tenantId, medicalStaff) -> {

            medicalStaff.forEach(medical -> {
                medical.setUpdateTime(null);
                medical.setCreateTime(null);
                medical.setPushStatus(null);
                medical.setTenantId(null);
                String json = "[" + JSONUtil.toJsonStr(medical) + "]";
                log.info("入参：{}", json);
                try {
                    R<JSONObject> jsonObjectR = DataSender.sendData(Type.DOCTOR_NURSE, 1, json, tenantId.intValue());
                    log.info("推送医护人员信息返回结果：{}", jsonObjectR);
                    if (jsonObjectR.getCode() == 0 || medical.getRetryConunt() >= 5) {
                        medical.setPushStatus(1);
                        medicalStaffService.updateById(medical);
                    } else {//就重试5次
                        medical.setRetryConunt(medical.getRetryConunt() + 1);
                        medicalStaffService.updateById(medical);
                    }
                } catch (Exception e) {
                    log.error("异常：{}", e);
                }
            });
        });
        log.info("结束执行医护人员数据推送...");
    }


    /**
     * 接警信息 t_emergency_call
     */
    public void rescueRecordAgencyTime() {
        log.info("开始执行 接警信息数据推送...");

        //查询已经推送的
        List<TEmergencyCall> tEmergencyCalls = emergencyCallService.list(new LambdaQueryWrapper<TEmergencyCall>().eq(TEmergencyCall::getPushStatus, 0));
        if (ObjectUtil.isEmpty(tEmergencyCalls)) {
            log.error("没有需要推送的接警信息数据...");
        }

        Map<Long, List<TEmergencyCall>> groupedByTenantId = tEmergencyCalls.stream().collect(Collectors.groupingBy(TEmergencyCall -> TEmergencyCall.getTenantId() != null ? TEmergencyCall.getTenantId() : 0L));

        groupedByTenantId.forEach((tenantId, emergencyCall) -> {
            emergencyCall.forEach(emergency -> {
                emergency.setCreateTime(null);
                emergency.setUpdateTime(null);
                emergency.setPushStatus(null);
                emergency.setTenantId(null);
                String json = "[" + JSONUtil.toJsonStr(emergency) + "]";
                log.info("入参：{}", json);
                try {
                    R<JSONObject> jsonObjectR = DataSender.sendData(Type.RESCUE_RECORD_AGENCY_PATIENT, 1, json, tenantId.intValue());
                    log.info("推送接警信息返回结果：{}", jsonObjectR);
                    if (jsonObjectR.getCode() == 0 || emergency.getRetryConunt() >= 5) {
                        emergency.setPushStatus(1);
                        emergencyCallService.updateById(emergency);
                    } else {//就重试5次
                        emergency.setRetryConunt(emergency.getRetryConunt() + 1);
                        emergencyCallService.updateById(emergency);
                    }
                } catch (Exception e) {
                    log.error("异常：{}", e);
                }
            });
        });
        log.info("结束执行 接警信息数据推送...");
    }


    /**
     * 院前急救:急救时间节点信息t_emergency_time_node
     */
    public void emergencyAgencyTime() {
        log.info("开始执行 急救时间节点信息数据推送...");
        //查表
        List<TEmergencyTimeNode> emergencyTimeNodeList = emergencyTimeNodeService.list(new LambdaQueryWrapper<TEmergencyTimeNode>().eq(TEmergencyTimeNode::getPushStatus, 0));
        if (ObjectUtil.isEmpty(emergencyTimeNodeList)) {
            log.error("没有需要推送的急救时间节点信息数据...");
        }

        Map<Long, List<TEmergencyTimeNode>> groupedByTenantId = emergencyTimeNodeList.stream().collect(Collectors.groupingBy(TEmergencyTimeNode -> TEmergencyTimeNode.getTenantId() != null ? TEmergencyTimeNode.getTenantId() : 0L));

        groupedByTenantId.forEach((tenantId, TEmergencyTimeNode) -> {
            TEmergencyTimeNode.forEach(emergency -> {

                emergency.setCreateTime(null);
                emergency.setUpdateTime(null);
                emergency.setPushStatus(null);
                emergency.setTenantId(null);
                String json = "[" + JSONUtil.toJsonStr(emergency) + "]";
                log.info("入参：{}", json);
                try {
                    R<JSONObject> jsonObjectR = DataSender.sendData(Type.RESCUE_RECORD_AGENCY_TIME, 1, json, tenantId.intValue());
                    log.info("推送急救时间节点信息返回结果：{}", jsonObjectR);
                    if (jsonObjectR.getCode() == 0 || emergency.getRetryConunt() >= 5) {
                        emergency.setPushStatus(1);
                        emergencyTimeNodeService.updateById(emergency);
                    } else {//就重试5次
                        emergency.setRetryConunt(emergency.getRetryConunt() + 1);
                        emergencyTimeNodeService.updateById(emergency);
                    }
                } catch (Exception e) {
                    log.error("异常：{}", e);
                }
            });

        });
        log.info("结束执行 急救时间节点信息数据推送...");
    }


    /**
     * 院前急救：急救任务各时间段用时情况
     */
    public void emergencyRecordTaskTime() {
        log.info("开始执行 急救任务各时间段用时情况数据推送...");

        //查询未推送的数据
        List<TEmergencyTaskTime> tEmergencyTaskTimes = emergencyTaskTimeService.list(new LambdaQueryWrapper<TEmergencyTaskTime>().eq(TEmergencyTaskTime::getPushStatus, 0));
        if (ObjectUtil.isEmpty(tEmergencyTaskTimes)) {
            log.error("没有需要推送的急救任务各时间段用时情况数据...");
        }
        Map<Long, List<TEmergencyTaskTime>> groupedByTenantId = tEmergencyTaskTimes.stream().collect(Collectors.groupingBy(TEmergencyTaskTime -> TEmergencyTaskTime.getTenantId() != null ? TEmergencyTaskTime.getTenantId() : 0L));

        groupedByTenantId.forEach((tenantId, TEmergencyTaskTime) -> {

            TEmergencyTaskTime.forEach(emergency -> {
                emergency.setCreateTime(null);
                emergency.setUpdateTime(null);
                emergency.setPushStatus(null);
                emergency.setTenantId(null);
                String json = "[" + JSONUtil.toJsonStr(emergency) + "]";
                log.info("入参：{}", json);
                try {
                    R<JSONObject> jsonObjectR = DataSender.sendData(Type.RESCUE_RECORD_TASK_TIME, 1, json, tenantId.intValue());
                    log.info("推送急救任务各时间段用时情况返回结果：{}", jsonObjectR);
                    if (jsonObjectR.getCode() == 0 || emergency.getRetryConunt() >= 5) {
                        emergency.setPushStatus(1);
                        emergencyTaskTimeService.updateById(emergency);
                    } else {//就重试5次
                        emergency.setRetryConunt(emergency.getRetryConunt() + 1);
                        emergencyTaskTimeService.updateById(emergency);
                    }
                } catch (Exception e) {
                    log.error("异常：{}", e);
                }
            });
        });

        log.info("结束执行 急救任务各时间段用时情况数据推送...");
    }


    /**
     * 各任务的诊断情况
     */
    public void emergencyRecordTaskDiagnosis() {
        log.info("开始执行 各任务的诊断情况数据推送...");
        //查未推送的
        List<TEmergencyDiagnosis> tEmergencyDiagnoses = emergencyDiagnosisService.list(new LambdaQueryWrapper<TEmergencyDiagnosis>().eq(TEmergencyDiagnosis::getPushStatus, 0));
        if (ObjectUtil.isEmpty(tEmergencyDiagnoses)) {
            log.error("没有需要推送的各任务的诊断情况数据...");
        }
        Map<Long, List<TEmergencyDiagnosis>> groupedByTenantId = tEmergencyDiagnoses.stream().collect(Collectors.groupingBy(TEmergencyDiagnosis -> TEmergencyDiagnosis.getTenantId() != null ? TEmergencyDiagnosis.getTenantId() : 0L));

        groupedByTenantId.forEach((tenantId, emergencyDiagnosis) -> {

            emergencyDiagnosis.forEach(emergency -> {
                emergency.setCreateTime(null);
                emergency.setUpdateTime(null);
                emergency.setPushStatus(null);
                emergency.setTenantId(null);
                String json = "[" + JSONUtil.toJsonStr(emergency) + "]";
                log.info("入参：{}", json);
                try {
                    R<JSONObject> jsonObjectR = DataSender.sendData(Type.RESCUE_RECORD_TASK_DIAGNOSIS, 1, json, tenantId.intValue());
                    log.info("推送各任务的诊断情况返回结果：{}", jsonObjectR);
                    if (jsonObjectR.getCode() == 0 || emergency.getRetryConunt() >= 5) {
                        emergency.setPushStatus(1);
                        emergencyDiagnosisService.updateById(emergency);
                    } else {//就重试5次
                        emergency.setRetryConunt(emergency.getRetryConunt() + 1);
                        emergencyDiagnosisService.updateById(emergency);
                    }
                }catch (Exception e){
                    log.error("异常：{}", e);
                }
            });
        });
        log.info("结束执行 各任务的诊断情况数据推送...");
    }

    /**
     * 车辆实时位置信息
     */
    public void vehicleRealTimeLocation() {
        log.info("开始执行 车辆定时位置数据推送...");
        //查全部
        List<TCarRealTimeLocation> list = carRealTimeLocationService.list(null);
        if (ObjectUtil.isEmpty(list)) {
            log.error("没有需要推送的车辆实时位置数据...");
        }
        Map<Long, List<TCarRealTimeLocation>> groupedByTenantId = list.stream()
                .collect(Collectors.groupingBy(
                        TCarRealTimeLocation -> TCarRealTimeLocation.getTenantId() != null ? TCarRealTimeLocation.getTenantId() : 0L
                ));

        groupedByTenantId.forEach((tenantId, carRealTimeLocationList) -> {


            Integer size = carRealTimeLocationList.size();
            int count = 50; // 每组的数据条数
            int groupSize = (size + count - 1) / count; // 计算需要的组数

            for (int i = 0; i < groupSize; i++) {
                // 计算当前组的起始和结束索引
                int startIndex = i * count;
                int endIndex = Math.min(startIndex + count, size); // 防止越界

                // 截取当前组的数据
                List<TCarRealTimeLocation> subList = carRealTimeLocationList.subList(startIndex, endIndex);

                // 清理每个对象中的冗余字段
                for (TCarRealTimeLocation data : subList) {
                    data.setTenantId(null);
                    data.setIsDeleted(null);
                }

                // 转换为 JSON 格式
                String json = JSONUtil.toJsonStr(subList);
                log.info("入参：{}", json);

                try {
                    // 推送当前组的数据
                    R<JSONObject> jsonObjectR = DataSender.sendData(
                            Type.VEHICLE_REAL_TIME_LOCATION,
                            subList.size(),
                            json,
                            tenantId.intValue()
                    );
                    log.info("推送返回结果：{}", jsonObjectR);
                } catch (Exception e) {
                    log.error("异常：{}", e);
                }
            }
        });
        log.info("结束执行 车辆定时位置数据推送...");
    }

}
